

namespace NodeBasedSkillEditor.Model.Node.RT
{
    public class Node_ExecuteQueue_RT : RT_Node
    {
        public RT_FlowPort FlowIn_RT;

        public RT_FlowPort[] FlowOut_RT;

        public Node_ExecuteQueue_RT(Node_ExecuteQueue sourceData, RT_DAG parentDag) : base(sourceData, parentDag)
        {
            FlowIn_RT = new RT_FlowPort(EPortIOType.Input, sourceData.FlowIn, this);

            FlowOut_RT = BuildRTPortArrayFromGroup<RT_FlowPort>(EPortIOType.Output, sourceData.FlowOut);
        }

        public override (EDagExeState, RT_Node) ForewardExecute(DAG_Executor executor)
        {
            if (FlowOut_RT.Length > 0)
            {
                var info = new ExecuteQueue_Info();
                executor.SetExeInfoOfNode(this, info);

                var (forwardPort, index) = GetFirstValidFlowoutPort(info.NextIndex);
                if (forwardPort != null)
                {
                    info.NextIndex = index + 1;
                    return TryForewardByPort(forwardPort);
                }
            }
            return (EDagExeState.Backward, null);
        }

        public override (EDagExeState, RT_Node) BackwardExecute(DAG_Executor executor)
        {
            if (FlowOut_RT.Length > 0)
            {
                var info = executor.GetExeInfoOfNode(this) as ExecuteQueue_Info;
                if (info != null)
                {
                    var (forwardPort, index) = GetFirstValidFlowoutPort(info.NextIndex);
                    if (forwardPort != null)
                    {
                        info.NextIndex = index + 1;
                        return TryForewardByPort(forwardPort);
                    }
                }
            }
            return (EDagExeState.Backward, null);
        }

        (RT_FlowPort, int) GetFirstValidFlowoutPort(int start)
        {
            while (start >= 0 && start < FlowOut_RT.Length)
            {
                var port = FlowOut_RT[start];
                if (port.LinkedPortInWorkingDirection != null)
                {
                    return (port, start);
                }
                else
                {
                    start++;
                }
            }
            return (null, -1);
        }

    }

    public class ExecuteQueue_Info : RT_NodeExeInfo
    {
        public int NextIndex = 0;
    }
}